
package UI;

import Action.KeyInput;
import Action.MouseInput;
import Object.DanhSachConVat;
import Object.BienToanCuc;
import Object.ConGa;
import Object.GioTrung;
import Object.ConNgan;
import Object.ConVit;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class Game extends Canvas implements Runnable {
    
    //<editor-fold defaultstate="collapsed" desc="1. danh sách biến">
    public static boolean running = false;
    private Thread thread;
    
    private DanhSachConVat c;
    public static GioTrung giotrung;
    private Menu menu;
    
    public static enum STATE {
        MENU,
        GAME
    }; 
    public static STATE state = STATE.MENU;
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="2. khởi tạo">
     private void init() {
        c = new DanhSachConVat();
        giotrung = new GioTrung(200, 589);
        
        menu = new Menu();
        
        addMouseListener(new MouseInput(this));
        addKeyListener(new KeyInput(this));
    }

    private void reStart() {
        BienToanCuc.diemhungtrung = 0;
        BienToanCuc.diemhungtrat = 0;
        BienToanCuc.tocdovatroi = 5;
        BienToanCuc.capdo = 0;
        c.clearEntity();
    }
    
    public static void main(String[] args) {
        Game game = new Game();
        game.setPreferredSize(new Dimension(500,700));
        
        JFrame jframe = new JFrame("Trò Chơi Hứng Trứng");
        jframe.add(game);
        jframe.pack();
        jframe.setResizable(false);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setLocationRelativeTo(null);
        jframe.setVisible(true);
        
        game.start();
    }
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="3. đánh dấu">
    private void tick() {
        if(state == STATE.GAME) {
            giotrung.tick();
            c.tick();
        }
        else {
            
        }   
    }
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="4. vẽ">
    private void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null) {
            createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        
        //vẽ backgroud
        Path p = Paths.get(Paths.get("").toAbsolutePath().toString());
        String pimg = p.toString() + "//src//Images/backgroud.png";
        File fimg = new File(pimg);
        Image image;
        try {
            image = ImageIO.read(fimg);
            g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
            
        } catch (IOException ex) {
            Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
        }
        if(state == STATE.GAME) {
            /////////////////////////////////
            //vẽ đường trên
            g.drawLine(10, 120, 500, 120);

            //vẽ đối tượng
            c.render(g);
            giotrung.render(g);

            //vẽ điểm
            g.drawString("điểm cộng: " +String.valueOf(BienToanCuc.diemhungtrung), 10, 699);
            g.drawString("điểm trừ: " + String.valueOf(BienToanCuc.diemhungtrat), 100, 699);
            //vẽ đường dưới
            g.drawLine(10, 680, 500, 680);
            /////////////////////////////////
        }
        else {
            menu.render(g);
        }
        g.dispose();
        bs.show();
    }
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="5. thao tác bàn phím">
    public void keyPressed(KeyEvent e) {
        int keycode = e.getKeyCode();
            if(keycode == KeyEvent.VK_G) {
                c.addEntity(new ConGa(10, 15, this));
            }
            if(keycode == KeyEvent.VK_V) {
                c.addEntity(new ConVit(428, 15, this));
            }
            if(keycode == KeyEvent.VK_N) {
                c.addEntity(new ConNgan(209, 15, this));
            }
            if(keycode == KeyEvent.VK_LEFT) {
                if(giotrung.getX() >= 0) {
                    giotrung.setX(giotrung.getX() - 30);
                    if(giotrung.getX() <= 0) {
                        giotrung.setX(0);
                        return;
                    }
                    
                }
            }
            if(keycode == KeyEvent.VK_RIGHT) {
                if(giotrung.getX() <= 410) {
                    giotrung.setX(giotrung.getX() + 30);
                    if(giotrung.getX() >= 410) {
                        giotrung.setX(410);
                    } 
                }
            }
    }
    
    public void keyReleased(KeyEvent e) {
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="thread">
    private synchronized void start() {
        if(running)
            return;
        running = true;
        thread = new Thread(this);
        thread.start();
    }
    
    private synchronized void stop() {
        if(!running)
            return;
        running = false;
        try {
            thread.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.exit(1);
    }
    //</editor-fold>
    
    @Override
    public void run() {
        init();
        long lasttime = System.nanoTime();
        final double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        
        int updates = 0;
        int  frames = 0;
        long timer = System.currentTimeMillis();
        
        while(running) {
           long now = System.nanoTime();
           delta += (now - lasttime) / ns;
           lasttime = now;
           if(delta >= 1) {
               tick();
               updates++;
               delta--;
           }
           render();
           frames++;
           
           if(System.currentTimeMillis() - timer > 1000) {
               timer += 1000;
               System.out.println(updates + " Ticks, Fps " + frames);
               updates = 0;
               frames = 0;
           }
           
           if(BienToanCuc.diemhungtrat >= 3) {
               reStart();
               state = STATE.MENU;
           }
       }
       stop();
    }
}
